package com.army.modules.host.job;

import com.army.modules.host.entity.HostWater;
import com.army.modules.host.job.listener.FileToDataJobListener;
import com.army.modules.host.job.listener.FileToDataWriter;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.task.SimpleAsyncTaskExecutor;

import java.net.MalformedURLException;

@Slf4j
@Configuration
@AllArgsConstructor
public class FileToData {
    private final JobLauncher jobLauncher;
    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;
    private  final FileToDataJobListener fileToDataJobListener;
    private final FileToDataWriter fileToDataWriter;

    /**
     * 读取回盘文件更新交易明细
     *
     * @param jobParameters jobParameters
     */
    public void run(JobParameters jobParameters) throws Exception {

        try {
            jobLauncher.run(readFileJob(), jobParameters);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Bean
    public Job readFileJob() throws MalformedURLException {
        return jobBuilderFactory.get("readFileJob")
                .incrementer(new RunIdIncrementer())
                .start(readFileStep())
                .listener(fileToDataJobListener)
                .build();
    }


    @Bean
    public SimpleAsyncTaskExecutor simpleAsyncTaskExecutor(){
        SimpleAsyncTaskExecutor simpleAsyncTaskExecutor = new SimpleAsyncTaskExecutor("CreateBankFile-");
        simpleAsyncTaskExecutor.setConcurrencyLimit(10);
        simpleAsyncTaskExecutor.setDaemon(true);
        return simpleAsyncTaskExecutor;
    }

    @Bean
    public Step readFileStep() throws MalformedURLException {
          return stepBuilderFactory.get("readFileStep")
                  .<HostWater, HostWater>chunk(10)
                .reader(readFileItemReader(""))
                .writer(fileToDataWriter)
                .taskExecutor(simpleAsyncTaskExecutor())
                .throttleLimit(30)
                .build();

    }
    @Bean(destroyMethod = "")
    @StepScope
    public FlatFileItemReader<HostWater> readFileItemReader( @Value("#{jobParameters['receiveFilePath']}") String receiveFilePath) throws MalformedURLException {
        String delimiter="$";
        FlatFileItemReader<HostWater> reader = new FlatFileItemReader<>();
        reader.setResource(new FileSystemResource(receiveFilePath));
        reader.setEncoding("UTF-8");
        reader.setLinesToSkip(1);
        DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
        //全局流⽔号$核⼼流⽔号$借⽅账号$贷⽅账号$核⼼⽇期$核⼼时间$交易结
        tokenizer.setNames("globalNo","coreNo","borrowAcct","loansAcct","transDate","transTime","transResult");
        DefaultLineMapper<HostWater> mapper = new DefaultLineMapper<>();
        tokenizer.setDelimiter(delimiter);
        mapper.setLineTokenizer(tokenizer);
        mapper.setFieldSetMapper(fieldSet -> {
            HostWater hostWater = new HostWater();
            hostWater.setGlobalNo(fieldSet.readString("globalNo"));
            hostWater.setCoreNo(fieldSet.readString("coreNo"));
            hostWater.setBorrowAcct(fieldSet.readString("borrowAcct"));
            hostWater.setLoansAcct(fieldSet.readString("loansAcct"));
            hostWater.setTransDate(fieldSet.readString("transDate"));
            hostWater.setTransTime(fieldSet.readString("transTime"));
            hostWater.setTransResult(fieldSet.readString("transResult"));
            return hostWater;
        });
        mapper.afterPropertiesSet();
        reader.setLineMapper(mapper);
        return reader;
    }
}
